<template>
  <el-dialog :model-value="visible" @update:model-value="handleVisibleChange" width="1000px" title="选择部门/人员">
    <div class="dialog-content">
      <div class="dialog-left">
        <el-input v-model="search" placeholder="搜索" suffix-icon="el-icon-search" clearable @input="filterTree" />
        <div class="custom-slot">
          <slot name="custom-content"></slot>
        </div>
        <el-tree ref="tree" :data="filteredTreeData" :props="treeProps" node-key="id" default-expand-all
          @node-click="handleNodeClick" />
      </div>
      <el-divider direction="vertical" style="height: auto" />
      <div class="dialog-right">
        <ProTable ref="proTable" :columns="columns" :data="selectedMembers" :toolButton="false">
          <template #tableHeader="scope">
          </template>
          <template #operation="scope">
            <SButton :buttonProps="{ type: 'primary', link: true }" buttonText="移除" />
          </template>
        </ProTable>
      </div>
    </div>
    <template v-slot:footer>
      <div class="dialog-footer">
        <el-button @click="handleCancel">取消</el-button>
        <el-button type="primary" @click="handleConfirm">确定</el-button>
      </div>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
import { ref, defineProps, defineEmits, watch, computed, onMounted, reactive } from 'vue';
import { ElTree, ElTable, ElButton, ElInput, ElDialog } from 'element-plus';
import { ColumnProps } from '../ProTable/interface';
import ProTable from "@/components/ProTable/index.vue";
import SButton from "@/components/SButton/index.vue";

interface TreeNode {
  id: number;
  label: string;
  type: 'company' | 'department' | 'person';
  children?: TreeNode[];
  members?: any[];
}

const props = defineProps<{
  visible: boolean;
  data: TreeNode[];
}>();

const columns = reactive<ColumnProps<any>[]>([
  { type: "selection", fixed: "left", width: 50 },
  { prop: "name", label: "姓名", width: 160 },
  { prop: "department", label: "部门" },
  { prop: "company", label: "单位" },
  { prop: "operation", label: "操作", width: 80 }
]);

const emit = defineEmits<{
  (e: 'update:visible', value: boolean): void;
  (e: 'confirm', selected: any[]): void;
  (e: 'cancel'): void;
}>();

const search = ref('');
const selectedMembers = ref<any[]>([]);
const tree = ref<InstanceType<typeof ElTree>>();

const treeProps = {
  label: 'label',
  children: 'children',
};

const filteredTreeData = computed(() => {
  const filter = (nodes: TreeNode[]): TreeNode[] => {
    return nodes.filter(node => {
      if (node.children) {
        node.children = filter(node.children);
      }
      return node.label.includes(search.value) || (node.children && node.children.length > 0);
    });
  };
  return filter(props.data);
});

const getAllMembers = (nodes: TreeNode[]): any[] => {
  let members: any[] = [];
  nodes.forEach(node => {
    if (node.members) {
      members = members.concat(node.members);
    }
    if (node.children) {
      members = members.concat(getAllMembers(node.children));
    }
  });
  return members;
};

onMounted(() => {
  selectedMembers.value = getAllMembers(props.data);
});

const handleNodeClick = (data: TreeNode) => {
  console.log(data);

  if (data.type === 'company' || data.type === 'department') {
    selectedMembers.value = data.members || [];
  } else if (data.type === 'person') {
    selectedMembers.value = [data];
  }
};

const handleConfirm = () => {
  emit('confirm', selectedMembers.value);
};

const handleCancel = () => {
  emit('cancel');
};

const handleVisibleChange = (value: boolean) => {
  emit('update:visible', value);
};

const filterTree = () => {
  tree.value?.filter(search.value);
};
</script>

<style scoped lang="scss">
// :deep(.el-dialog__body) {
//   height: 500px;
// }

.dialog-content {
  display: flex;
  height: 500px;
  overflow: hidden;

  .dialog-left {
    width: 20%;

    .custom-slot {
      // margin-bottom: 20px;
      margin: 1rem 0;
    }
  }

  .dialog-right {
    width: 78%;
    margin-left: 2%;
  }

}

.dialog-footer {
  flex-shrink: 0;
  padding: 10px;
  border-top: 1px solid #e8e8e8;
  display: flex;
  justify-content: center;
}
</style>
